home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / WINPROGS / WUNZ20SR.ZIP / SOUND.C < prev    next >
C/C++ Source or Header  |  1993-03-11  |  11KB  |  322 lines

  1. #include "sound.h"
  2. #include "wizunzip.h"
  3. #include "helpids.h"
  4. #include <mmsystem.h>
  5.  
  6. /* WizUnZip sound control module, sound.c. 
  7.  * This module controls what sound WizUnZip makes after during or after extracting a file.
  8.  * All users can optionally produce a beep after unzipping. Users with Windows 3.1
  9.  * or Windows 3.0 + Multimedia extensions can play wave files. 
  10.  * WizUnZip uses the presence of the DLL MMSYSTEM.DLL to determine whether MM
  11.  * capability is present.  It further queries the number of wave devices in
  12.  * the system to see if wave playing hardware is present.   This approach
  13.  * gives maximum system useability without causing Windows errors such as
  14.  * "Can't find dynalink!"
  15.  */
  16.  
  17. #define SNDPLAYSOUND_ORD 2 /* sndPlaySound ordinal in MMSYSTEM.DLL */
  18. #define WAVEOUTGETNUMDEVS_ORD 401 /* waveOutGetNumDevs ordinal    */
  19. #define MAXFILTERBUF 50
  20.  
  21. static char __based(__segname("STRINGS_TEXT")) szBeepOnFinish[] = "Beep";
  22. static char __based(__segname("STRINGS_TEXT")) szMMSystemDll[] = "MMSYSTEM.DLL";
  23. static char __based(__segname("STRINGS_TEXT")) szDfltWaveFile[] = "WIZUNZIP.WAV";
  24. static char __based(__segname("STRINGS_TEXT")) szSoundNameKey[] = "SoundName"; /* key in .INI */
  25. static char __based(__segname("STRINGS_TEXT")) szSoundOptKey[] = "SoundOption";
  26. static char __based(__segname("STRINGS_TEXT")) szWaveBrowseTitle[] = "Browse Sound Files";
  27. static char __based(__segname("STRINGS_TEXT")) gszFilter[MAXFILTERBUF] = 
  28.                                     "Wave Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0\0";
  29. static char  *SoundOptsTbl[] = /* for .INI file */
  30.     {"none", "beep", "PlayDuring", "PlayAfter" };
  31.  
  32. static HINSTANCE hinstMMSystem; /* MMSystem DLL instance */
  33. static FARPROC lpSndPlaySound;    /* pointer to SndPlaySound()    */
  34. static FARPROC lpWaveOutGetNumDevs;    /* pointer to WaveOutGetNumDevs() */
  35. static BOOL CanPlayWave(void);
  36. static WORD uSoundButtonSelected = IDM_SOUND_NONE; /* state of sound option */
  37. static WORD uSoundButtonSelectedTmp; /* state of sound option while in dialog box */
  38.  
  39.  
  40. /* Forward Refs
  41.  */
  42. static BOOL DoOpenFile(HWND hWnd, LPSTR lpDestFileName);
  43. static BOOL CanPlayWave(void);
  44.  
  45. /* Test for Wave Playing Capability
  46.  */
  47. static BOOL CanPlayWave(void)
  48. {
  49. static bTestedForWave = FALSE; /* true if test for wave playing has been done */
  50. static bCanPlayWave = FALSE;    /* true if system can play wave    */
  51. int    nPrevErrorMode;            /* previous error mode                    */
  52.  
  53.     if (bTestedForWave)            /* deja vu ? */
  54.         return(bCanPlayWave);
  55.  
  56.     bTestedForWave = TRUE;
  57.     nPrevErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX);
  58.     hinstMMSystem = LoadLibrary(szMMSystemDll);
  59.     SetErrorMode(nPrevErrorMode);
  60.     if (hinstMMSystem >  HINSTANCE_ERROR)
  61.     {
  62.         /* If can't load the function which looks up no. wave out devices or
  63.          * number of wave output devices is zero, we can't play waves.
  64.          */
  65.         if ((lpWaveOutGetNumDevs = 
  66.             GetProcAddress(hinstMMSystem, MAKEINTRESOURCE(WAVEOUTGETNUMDEVS_ORD))) == NULL ||
  67.             (*lpWaveOutGetNumDevs)() == 0 ||
  68.             (lpSndPlaySound = 
  69.             GetProcAddress(hinstMMSystem, MAKEINTRESOURCE(SNDPLAYSOUND_ORD))) == NULL)
  70.         {
  71.             FreeLibrary(hinstMMSystem);    /* unload library    */
  72.         }
  73.         else /* we're set to play waves */
  74.         {
  75.             bCanPlayWave = TRUE;    /* flag that we can play waves    */
  76.         }
  77.     }
  78.     return bCanPlayWave;
  79. }
  80.  
  81. /* Migrate Sound Options translates the former beep-on-finish option into 
  82.  * one of the first 2 of the 4 sound options.
  83.  */
  84. void MigrateSoundOptions(void)
  85. {
  86. UINT SoundOptsTableIndex;
  87.  
  88.        GetProfileString(szAppName, szBeepOnFinish, szNo, lpumb->szBuffer, OPTIONS_BUFFER_LEN);
  89.     SoundOptsTableIndex = (UINT)(!lstrcmpi(lpumb->szBuffer, szNo) ? 0 : 1);
  90.     WritePrivateProfileString(szAppName, szLBSelectionKey, 
  91.                                 SoundOptsTbl[SoundOptsTableIndex], 
  92.                                 szWizUnzipIniFile);
  93. }
  94.  
  95. /* Initialize Sound Options is called on WizUnZip start-up to read
  96.  * the sound option and sound name.
  97.  * Read the Sound Option to see if user wants beep, sound, or nothing.
  98.  * Read chosen sound name or wave file.
  99.  */
  100. void InitSoundOptions(void)
  101. {
  102.     GetPrivateProfileString(szAppName, szSoundOptKey, SoundOptsTbl[0], 
  103.                             lpumb->szBuffer, OPTIONS_BUFFER_LEN, 
  104.                             szWizUnzipIniFile);
  105.     lpumb->szBuffer[255] = '\0';    /* force truncation */
  106.     for (uSoundButtonSelected = IDM_SOUND_NONE; 
  107.          uSoundButtonSelected < IDM_SOUND_WAVE_AFTER && 
  108.          lstrcmpi(lpumb->szBuffer, SoundOptsTbl[uSoundButtonSelected-IDM_SOUND_NONE]) ;
  109.          uSoundButtonSelected++)
  110.         ;
  111.  
  112.     /* Do range check on sound option. Set to none if necessary.
  113.      */
  114.     if (uSoundButtonSelected > IDM_SOUND_WAVE_AFTER ||
  115.         (uSoundButtonSelected > IDM_SOUND_BEEP && 
  116.          !CanPlayWave()))
  117.         uSoundButtonSelected = IDM_SOUND_NONE;
  118.         
  119.     GetPrivateProfileString(szAppName, szSoundNameKey, szDfltWaveFile, 
  120.                             lpumb->szSoundName, WIZUNZIP_MAX_PATH, 
  121.                             szWizUnzipIniFile);
  122. }
  123.  
  124.  
  125. /* Play Sound During extraction, test, or display  if requested.
  126.  * Don't use a default if nothing specified.
  127.  */
  128. void SoundDuring(void)
  129. {
  130.     if (uSoundButtonSelected == IDM_SOUND_WAVE_DURING && CanPlayWave())
  131.     {
  132.             (*lpSndPlaySound)((LPSTR)lpumb->szSoundName, SND_ASYNC|SND_NOSTOP|SND_NODEFAULT);        
  133.     }
  134. }
  135.  
  136. /* Play Sound After extraction, test, or display  if requested.
  137.  */
  138. void SoundAfter(void)
  139. {
  140.     switch (uSoundButtonSelected) {
  141.     case IDM_SOUND_BEEP:
  142.         MessageBeep(1);
  143.         break;
  144.     case IDM_SOUND_WAVE_AFTER:
  145.         if (CanPlayWave())
  146.             (*lpSndPlaySound)((LPSTR)lpumb->szSoundName, SND_ASYNC|SND_NOSTOP);
  147.             
  148.         break;
  149.     }
  150. }
  151.  
  152.  
  153.  
  154. /* Do File Open Dialog calls the common dialog function GetOpenFileName()
  155.  * to browse and select a table file.
  156.  */
  157. static BOOL DoOpenFile(HWND hWnd, LPSTR lpDestFileName)
  158. {
  159. BOOL fRetCode = FALSE;    /* assume failure                */
  160. DWORD dwExtdError;
  161.  
  162.  
  163.  
  164.  
  165.  
  166.          lpumb->wofn.lStructSize       = sizeof(OPENFILENAME);
  167.          lpumb->wofn.hwndOwner         = (HWND)hWnd;
  168.          lpumb->wofn.hInstance         = (HANDLE)NULL;
  169.          lpumb->wofn.lpstrFilter       = gszFilter;
  170.          lpumb->wofn.lpstrCustomFilter = (LPSTR)NULL;
  171.          lpumb->wofn.nMaxCustFilter    = 0L;
  172.          lpumb->wofn.nFilterIndex      = 1L;
  173.          lpumb->wofn.lpstrFile         = lpDestFileName; 
  174.          lpDestFileName[0]                  = '\0'; 
  175.  
  176.          lpumb->wofn.nMaxFile          = (DWORD)WIZUNZIP_MAX_PATH;
  177.          lpumb->wofn.lpstrFileTitle    = (LPSTR)NULL; 
  178.          lpumb->wofn.nMaxFileTitle     = 0;
  179.          lpumb->wofn.lpstrInitialDir   = (LPSTR)NULL;
  180.          lpumb->wofn.lpstrTitle        = (LPSTR)szWaveBrowseTitle;
  181.          lpumb->wofn.Flags             = OFN_HIDEREADONLY|
  182.                                            OFN_PATHMUSTEXIST|
  183.                                            OFN_FILEMUSTEXIST|
  184.                                            OFN_NOCHANGEDIR|
  185.                                            OFN_SHOWHELP ;
  186.          lpumb->wofn.nFileOffset       = 0;
  187.          lpumb->wofn.nFileExtension    = 0;
  188.          lpumb->wofn.lpstrDefExt       = "WAV";
  189.          lpumb->wofn.lCustData         = 0L;
  190.           lpumb->wofn.lpfnHook          = (FARPROC)NULL;
  191.          lpumb->wofn.lpTemplateName    = (LPSTR)NULL;
  192.  
  193.     if ( GetOpenFileName( &(lpumb->wofn) ) )
  194.        {
  195.           HFILE   hFile;
  196.           OFSTRUCT ofstruct;
  197.  
  198.           hFile=OpenFile(lpumb->wofn.lpstrFile, &ofstruct, OF_EXIST);
  199.           if (hFile != -1)
  200.           {
  201.              fRetCode = TRUE;
  202.           }
  203. /* NOTE!!!  On a closed system (ie, not running on a network)
  204.  * this OpenFile call should NEVER fail.  This because we passed in the
  205.  * OFN_FILEMUSTEXIST flag to CD.  However, on a network system,
  206.  * there is a *very* small chance that between the time CD's checked
  207.  * for existance of the file and the time the call to OpenFile
  208.  * was made here, someone else on the network has deleted the file.
  209.  * MORAL: ALWAYS, ALWAYS, ALWAYS check the return code from your
  210.  * call to OpenFile() or _lopen.
  211.  */
  212.  
  213.        }
  214.         else /* dialog failed */
  215.         {
  216.             dwExtdError = CommDlgExtendedError();    /* get error code */
  217.         }
  218.     return(fRetCode);            /* return indication        */
  219. }
  220.  
  221. /****************************************************************************
  222.  
  223.     FUNCTION: SoundProc(HWND, unsigned, WORD, LONG)
  224.  
  225.     PURPOSE:  Processes messages for "Sound Options" dialog box of